package driver

import (
	"encoding/json"
	"errors"
	"fmt"
	"k8s.io/klog/v2"
	"math/rand"
	"sync"
)

type VirtualDeviceProtocolConfig struct {

}

type VirtualDeviceProtocolCommonConfig struct {

}

type VirtualDeviceVisitorConfig struct {
	DataType string `json:"dataType"`
}

type VirtualDevice struct {
	intValue int
	floatValue float64
	limit int64
	mutex sync.Mutex
	virtualProtocolConfig VirtualDeviceProtocolConfig
	protocolCommonConfig VirtualDeviceProtocolCommonConfig
	visitorConfig VirtualDeviceVisitorConfig
}

func (vd *VirtualDevice) SetConfig(protocolCommon,visitor,protocol []byte) (err error){
	vd.NewClient()
	if protocolCommon != nil{
		if err = json.Unmarshal(protocolCommon, &vd.protocolCommonConfig); err != nil {
			fmt.Printf("Unmarshal ProtocolCommonConfig error: %v\n", err)
			return err
		}
	}
	if visitor != nil{
		if err = json.Unmarshal(visitor, &vd.visitorConfig); err != nil {
			fmt.Printf("Unmarshal visitorConfig error: %v\n", err)
			return err
		}
	}

	if protocol != nil{
		if err = json.Unmarshal(protocol, &vd.virtualProtocolConfig); err != nil {
			fmt.Printf("Unmarshal ProtocolConfig error: %v\n", err)
			return err
		}
	}
	return nil
}

// ReadDeviceData  is an interface that reads data from a specific device, data is a type of string
func (vd *VirtualDevice) ReadDeviceData () (data interface{}, err error){
	if vd.visitorConfig.DataType == "int"{
		if vd.limit == 0{
			klog.Error("vd.limit should not be 0")
			return 0,errors.New("vd.limit should not be 0")
		}
		vd.intValue = rand.Intn(int(vd.limit))
		return vd.intValue,nil
	}else if vd.visitorConfig.DataType == "float"{
		if vd.limit == 0{
			klog.Error("vd.limit should not be 0")
			return 0,errors.New("vd.limit should not be 0")
		}
		vd.floatValue = rand.Float64()
		return vd.floatValue,nil
	}else{
		return "",errors.New("dataType don't exist")
	}
}

// WriteDeviceData is an interface that write data to a specific device, data's DataType is Consistent with configmap
func (vd *VirtualDevice) WriteDeviceData (data interface{}) (err error){
	vd.mutex.Lock()
	defer vd.mutex.Unlock()
	vd.limit = data.(int64)
	return nil
}

// StopDevice is an interface to disconnect a specific device
func (vd *VirtualDevice) StopDevice() (err error){
	fmt.Println("----------Stop Virtual Device Successful----------")
	return nil
}


func(vd *VirtualDevice) NewClient() {
	if vd.limit != 0{
		return
	}
	vd.limit = 100
}

// GetDeviceStatus is an interface to get the device status true is OK , false is DISCONNECTED
func (vd *VirtualDevice) GetDeviceStatus() (status bool){
	return true
}
